package com.atguigu.gulimall.order;

import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

/**
 * 使用RabbitMQ
 * 1.引入了amqp场景 RabbitAutoConfiguration就会生效
 * 2.给容器中自动配置了RabbitTemplate、AmqpAdmin、CachingConnectionFactory、RabbitMessagingTemplate
 * 所有的属性在@ConfigurationProperties(
 *     prefix = "spring.rabbitmq"
 * )
 * 3.在配置文件中配置spring.rabbitmq.xxxxxx
 * 4.@EnableRabbit: @Enablexxxx
 * 5.监听消息，使用@RabbitListener,必须开启@EnableRabbit
 *      @RabbitListener 类+方法上（监听那些队列即可）
 *      @RabbitHandler 方法上(重载区分不同的消息)
 *
 *  本地事务失效问题
 *  同一个对象内事务方法互调默认失效，原因:绕过了代理对象，事务使用代理对象来控制的
 *  解决：使用代理对象来调用事务方法
 *      1）、引入aop-starter spring-boot-starter-aop->引入了aspectj
 *      2）、@EnableAspectJAutoProxy(exposeProxy = true)：开启aspectj动态代理（没有接口也可以创建动态代理）
 *              对外暴露代理对象
 *      3）、本类互调调用对象,可以解决循环依赖
 *              @Autowired
 *              OrderServiceImpl o = (OrderServiceImpl)AopContext.currentProxy();
 * Seata控制分布式事务
 *  1)、每个微服务的数据库建一个undo_log表
 *  2)、安装事务协调器：seata-server  https://github.com/seata/seata/releases,
 *  3)、整合
 *      1.导入依赖 spring-cloud-starter-alibaba-seata seata-all-1.0.0
 *      2.解压并启动seata服务器 registry.conf注册中心配置 type = "nacos"
 *      3.所有想用到分布式事务的微服务使用seata DataSourceProxy代理自己的数据源
 *      4.file.conf vgroup_mapping.{application.name}-fescar-service-group = "default"
 *      5.给分布式大事务的入口标注 @GlobalTransactional//全局事务 @Transactional
 *      6.给每一个远程的小失误用 @Transactional
 *      7.启动测试
 *
 * RabbitMQ
 *   1、防止消息丢失：
 *      1）、做好消息确认机制(pulisher、consumer[手动ack])
 *      2）、每一个发送的消息都在数据库做好记录，定期将失败的消息在发送一遍
 *   2、消息重复：
 *      1）、业务应该设计成幂等性的、使用防重表(redis/mysql)、rabbitMQ的message的redelivered字段，可以获取是否被重新投入
 *   3、消息积压(消费者宕机、消费者消费能力不足、发送者发送的太多)
 *      1）、上线更多的消费者，
 *      2）、上线专门的队列消费服务，将消息先批量记录到数据库，离线处理
 *
 */
@EnableAspectJAutoProxy(exposeProxy = true)
@EnableFeignClients
@EnableRedisHttpSession
@EnableRabbit
@EnableDiscoveryClient
@SpringBootApplication
public class GulimallOrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimallOrderApplication.class, args);
    }

}
